package com.eds.exception;

import lombok.experimental.Accessors;

/**
 * 自定义业务处理异常类
 *
 * @author vvSmile
 * @date 2025-03-27 14:28:22
 */
@Accessors(chain = true)
public class BusException extends RuntimeException {

    /**
     * 默认错误码
     */
    public static final Integer DEFAULT_ERROR_CODE = 500;

    /**
     * 默认成功码
     */
    public static final Integer DEFAULT_SUCCESS_CODE = 200;

    /**
     * 错误码
     */
    private Integer code;

    /**
     * 错误数据
     */
    private Object data;

    /**
     * 完整构造方法
     *
     * @param code    错误码
     * @param message 错误信息
     * @param data    错误数据
     */
    public BusException(Integer code, String message, Object data) {
        super(message);
        this.code = code;
        this.data = data;
    }

    /**
     * 带错误码和消息的构造方法
     *
     * @param code    错误码
     * @param message 错误信息
     */
    public BusException(Integer code, String message) {
        this(code, message, null);
    }

    /**
     * 只带消息的构造方法，使用默认错误码
     *
     * @param message 错误信息
     */
    public BusException(String message) {
        this(DEFAULT_ERROR_CODE, message);
    }

    /**
     * 带异常信息的构造方法
     *
     * @param message 错误信息
     * @param cause   原始异常
     */
    public BusException(String message, Throwable cause) {
        super(message, cause);
        this.code = DEFAULT_ERROR_CODE;
        this.data = null;
    }

    /**
     * 获取异常信息
     *
     * @param ex 异常对象
     * @return 异常信息
     */
    public static String getMessage(Throwable ex) {
        if (isBusinessException(ex)) {
            return ((BusException) ex).getMessage();
        }
        return ex != null ? ex.getMessage() : "未知错误";
    }

    /**
     * 获取异常码
     *
     * @param ex 异常对象
     * @return 异常码
     */
    public static Integer getErrorCode(Throwable ex) {
        if (isBusinessException(ex)) {
            return ((BusException) ex).getCode();
        }
        return DEFAULT_ERROR_CODE;
    }

    /**
     * 获取异常数据
     *
     * @param ex 异常对象
     * @return 异常数据
     */
    public static Object getData(Throwable ex) {
        if (isBusinessException(ex)) {
            return ((BusException) ex).getData();
        }
        return null;
    }

    /**
     * 获取错误码
     */
    public Integer getCode() {
        return code;
    }

    /**
     * 快速创建业务异常
     *
     * @param message 错误信息
     * @return BusException
     */
    public static BusException error(String message) {
        return new BusException(DEFAULT_ERROR_CODE, message);
    }

    /**
     * 快速创建业务异常
     *
     * @param code    错误码
     * @param message 错误信息
     * @return BusException
     */
    public static BusException error(Integer code, String message) {
        return new BusException(code, message);
    }

    /**
     * 快速创建业务异常
     *
     * @param code    错误码
     * @param message 错误信息
     * @param data    错误数据
     * @return BusException
     */
    public static BusException error(Integer code, String message, Object data) {
        return new BusException(code, message, data);
    }

    /**
     * 判断是否为业务异常
     *
     * @param ex 异常对象
     * @return 是否为业务异常
     */
    public static boolean isBusinessException(Throwable ex) {
        return ex instanceof BusException;
    }

    /**
     * 设置错误码
     */
    public BusException setCode(Integer code) {
        this.code = code;
        return this;
    }

    /**
     * 获取错误数据
     */
    public Object getData() {
        return data;
    }

    /**
     * 设置错误数据
     */
    public BusException setData(Object data) {
        this.data = data;
        return this;
    }

    @Override
    public String toString() {
        return String.format("BusException(code=%d, message='%s', data=%s)",
                code, getMessage(), data);
    }
}